#include "FUSB302_UFP.h"
#include "fusb302Port.h"
#include "softI2c.h"
#include "osDispatcher.h"
#include "main.h"
#include "debug.h"
static LL_GPIO_InitTypeDef GPIO_InitStruct;
//	PA2: GPIO OUTPUT, FUSB302 SDA
//	PA3: GPIO OUTPUT, FUSB302 SCL
//	PA4: GPIO INPUT, FUSB302 INT

void fusb302I2cSclIn(void)
{
    GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void fusb302I2cSclOut(void)
{
    GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void fusb302I2cSclHigh(void)
{
    LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_3);
}

void fusb302I2cSclLow(void)
{
    LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_3);
}

void fusb302I2cSdaIn(void)
{
    GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void fusb302I2cSdaOut(void)
{
    GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void fusb302I2cSdaHigh(void)
{
    LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_2);
}

void fusb302I2cSdaLow(void)
{
    LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_2);
}

unsigned char fusb302I2cSdaRead(void)
{
    return LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_2);
}

void fusb302I2cDelay(void)
{
}

SoftI2cHandler fusb302I2cHandler =
    {
        .isErr = 0,
        .delay = fusb302I2cDelay,
        .sclHigh = fusb302I2cSclHigh,
        .sclIn = fusb302I2cSclIn,
        .sclLow = fusb302I2cSclLow,
        .sclOut = fusb302I2cSclOut,
        .sdaHigh = fusb302I2cSdaHigh,
        .sdaIn = fusb302I2cSdaIn,
        .sdaLow = fusb302I2cSdaLow,
        .sdaOut = fusb302I2cSdaOut,
        .sdaRead = fusb302I2cSdaRead,
};

void fusb302PortInit(void)
{
    softI2cInit(&fusb302I2cHandler);
}

FUSB302_ret_t fusb302I2cRead(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count)
{
    softI2cReadMultFromAddr(&fusb302I2cHandler, dev_addr, reg_addr, data, count);
    if (fusb302I2cHandler.isErr)
    {
        return FUSB302_ERR_READ_DEVICE;
    }
    return FUSB302_SUCCESS;
}

FUSB302_ret_t fusb302I2cWrite(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count)
{
    softI2cWriteMultToAddr(&fusb302I2cHandler, dev_addr, reg_addr, data, count);
    if (fusb302I2cHandler.isErr)
    {
        return FUSB302_ERR_WRITE_DEVICE;
    }
    return FUSB302_SUCCESS;
}

FUSB302_ret_t puDelayMs(uint32_t ms)
{
    //HAL_Delay(ms);
    LL_mDelay(ms);
    return FUSB302_SUCCESS;
}

uint8_t fusb302IntPin(void)
{
    //return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4);
    return LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_4);
}

void puStdPrint(char *str)
{
    PRINTF("%s", str);
}

uint16_t puClockMs(void)
{
    return (unsigned int)timestamp;
}
